home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / archiver / unix / zip19p1.zoo / vms / vms.c < prev    next >
C/C++ Source or Header  |  1992-08-18  |  19KB  |  760 lines

  1. /*************************************************************************
  2.  *                                                                       *
  3.  * VMS portions copyright (C) 1992 Igor Mandrichenko.                    *
  4.  * Permission is granted to any individual or institution to use, copy,  *
  5.  * or redistribute this software so long as all of the original files    *
  6.  * are included unmodified, that it is not sold for profit, and that     *
  7.  * this copyright notice is retained.                                    *
  8.  *                                                                       *
  9.  *************************************************************************/
  10.  
  11. /*
  12.  *  vms.c (zip) by Igor Mandrichenko    Version 2.1-1
  13.  *
  14.  *  Revision history:
  15.  *  ...
  16.  *  2.1-1       16-feb-1992     I.Mandrichenko  
  17.  *      Get file size from XABFHC and check bytes rest in file before
  18.  *      reading. 
  19.  *  2.1-2       2-mar-1992      I.Mandrichenko
  20.  *      Make code more standard
  21.  *  2.2         21-jun-1992     I.Mandrichenko
  22.  *      Free all allocated space, use more static storage.
  23.  *      Use memcompress() from bits.c (deflation) for block compression.
  24.  *      To revert to old compression method #define OLD_COMPRESS
  25.  */
  26.  
  27. #ifdef VMS                      /* For VMS only ! */
  28.  
  29. #define OLD_COMPRESS    /*To use old compression method define it.*/
  30.  
  31. #include <rms.h>
  32. #include <descrip.h>
  33. #include <syidef.h>
  34.  
  35. #ifndef VAXC
  36.                                 /* This definition may be missed */
  37. struct XAB {
  38.     unsigned char xab$b_cod;
  39.     unsigned char xab$b_bln;
  40.     short int xabdef$$_fill_1;
  41.     char *xab$l_nxt;
  42. };
  43.  
  44. #endif
  45.  
  46. #ifndef SYI$_VERSION
  47. #define SYI$_VERSION 4096       /* VMS 5.4 definition */
  48. #endif
  49.  
  50. #include "zip.h"
  51.  
  52. #define ERR(s)  !((s)&1)
  53.  
  54. #define RET_ERROR 1
  55. #define RET_SUCCESS 0
  56. #define RET_EOF 0
  57.  
  58. #define Kbyte 1024
  59.  
  60. typedef struct XAB *xabptr;
  61.  
  62. /*
  63. *   Extra record format
  64. *   ===================
  65. *   signature       (2 bytes)   = 'I','M'
  66. *   size            (2 bytes)
  67. *   block signature (4 bytes)
  68. *   flags           (2 butes)
  69. *   uncomprssed size(2 bytes)
  70. *   reserved        (4 bytes)
  71. *   data            (size-12 bytes)
  72. *   ....
  73. */
  74.  
  75.  
  76. /*
  77. *   Extra field signature and block signatures
  78. */
  79. #define SIGNATURE "IM"
  80. #define EXTBSL  4               /* Block signature length   */
  81. #define RESL    8
  82.  
  83. #define BC_MASK         07      /* 3 bits for compression type */       
  84. #define BC_STORED       0       /* Stored */
  85. #define BC_00           1       /* 0byte -> 0bit compression */
  86. #define BC_DEFL         2       /* Deflated */
  87.  
  88. struct extra_block
  89. {       ush     im_sig;
  90.         ush     size;
  91.         ulg     block_sig;
  92.         ush     flags;
  93.         ush     length;
  94.         ulg     reserved;
  95.         uch     body[1];        /* The actual size is unknown */
  96. };
  97.  
  98. #define FABSIG  "VFAB"
  99. #define XALLSIG "VALL"
  100. #define XFHCSIG "VFHC"
  101. #define XDATSIG "VDAT"
  102. #define XRDTSIG "VRDT"
  103. #define XPROSIG "VPRO"
  104. #define XKEYSIG "VKEY"
  105. #define VERSIG  "VMSV"
  106. /*
  107. *   Block sizes
  108. */
  109. #define FABL    (cc$rms_fab.fab$b_bln)
  110. #define RABL    (cc$rms_rab.rab$b_bln)
  111. #define XALLL   (cc$rms_xaball.xab$b_bln)
  112. #define XDATL   (cc$rms_xabdat.xab$b_bln)
  113. #define XFHCL   (cc$rms_xabfhc.xab$b_bln)
  114. #define XKEYL   (cc$rms_xabkey.xab$b_bln)
  115. #define XPROL   (cc$rms_xabpro.xab$b_bln)
  116. #define XRDTL   (cc$rms_xabrdt.xab$b_bln)
  117. #define XSUML   (cc$rms_xabsum.xab$b_bln)
  118. #define EXTHL   (4+EXTBSL+RESL)
  119. #define EXTL0   ((FABL + EXTHL)+        \
  120.                 (XFHCL + EXTHL)+        \
  121.                 (XPROL + EXTHL)+        \
  122.                 (XDATL + EXTHL)+        \
  123.                 (XRDTL + EXTHL))
  124.  
  125. #ifdef OLD_COMPRESS
  126. #define PAD     sizeof(uch)
  127. #else
  128. #define PAD     10*sizeof(ush)          /* Two extra bytes for compr. header */
  129. #endif
  130.  
  131. #define PAD0    (5*PAD)                 /* Reserve space for the case when
  132.                                         *  compression failes */
  133. static int _compress();
  134.  
  135. /***********************************
  136.  *   Function get_vms_attributes   *
  137.  ***********************************/
  138.  
  139. static uch *_compress_block();
  140. static int get_vms_version();
  141.  
  142. int get_vms_attributes(z)
  143.   struct zlist *z;
  144. /*
  145.  *      Get file VMS file attributes and store them into extent fields.
  146.  *      Store VMS version also.
  147.  *      On error leave z intact.
  148.  */
  149. {
  150.     int status;
  151.     uch *extra=(uch*)NULL, *scan;
  152.     extent extra_l;
  153.     static struct FAB fab;
  154.     static struct XABSUM xabsum;
  155.     static struct XABFHC xabfhc;
  156.     static struct XABDAT xabdat;
  157.     static struct XABPRO xabpro;
  158.     static struct XABRDT xabrdt;
  159.     xabptr x = (xabptr)NULL, xab_chain = (xabptr)NULL, last_xab = (xabptr)NULL;
  160.     int nk, na;
  161.     int i;
  162.     int rc=RET_ERROR;
  163.     char verbuf[80];
  164.     int verlen = 0;
  165.  
  166.     /*
  167.     *   Initialize RMS control blocks and link them
  168.     */
  169.  
  170.     fab =    cc$rms_fab;
  171.     xabsum = cc$rms_xabsum;
  172.     xabdat = cc$rms_xabdat;
  173.     xabfhc = cc$rms_xabfhc;
  174.     xabpro = cc$rms_xabpro;
  175.     xabrdt = cc$rms_xabrdt;
  176.  
  177.  
  178.     fab.fab$l_xab = (char*)&xabsum;
  179.     /*
  180.     *   Open the file and read summary information.
  181.     */
  182.     fab.fab$b_fns = strlen(z->name);
  183.     fab.fab$l_fna = z->name;
  184.  
  185.     status = sys$open(&fab);
  186.     if (ERR(status))
  187.     {
  188. #ifdef DEBUG
  189.         printf("get_vms_attributes: sys$open for file %s:\n  error status = %d\n",
  190.                z->name, status);
  191. #endif
  192.         goto err_exit;
  193.     }
  194.  
  195.     nk = xabsum.xab$b_nok;
  196.     na = xabsum.xab$b_noa;
  197. #ifdef DEBUG
  198.     printf("%d keys, %d alls\n", nk, na);
  199. #endif
  200.  
  201.     /*
  202.     *   Allocate XABKEY and XABALL blocks ind link them
  203.     */
  204.  
  205.     xabfhc.xab$l_nxt = (char*)&xabdat;
  206.     xabdat.xab$l_nxt = (char*)&xabpro;
  207.     xabpro.xab$l_nxt = (char*)&xabrdt;
  208.     xabrdt.xab$l_nxt = (char*)0L;
  209.  
  210.     xab_chain = (xabptr)(&xabfhc);
  211.     last_xab  = (xabptr)(&xabrdt);
  212.  
  213. #define INIT(ptr,size,init)     \
  214.         if( (ptr = (uch*)malloc(size)) == NULL )        \
  215.         {                                               \
  216.               printf( "get_vms_attributes: Insufficient memory.\n" );   \
  217.                       goto err_exit;                    \
  218.         }                                               \
  219.         *(ptr) = (init);
  220.     /*
  221.     *   Allocate and initialize all needed XABKEYs and XABALLs
  222.     */
  223.     for (i = 0; i < nk; i++)
  224.     {
  225.         struct XABKEY *k;
  226.         INIT(k, XKEYL, cc$rms_xabkey);
  227.         k->xab$b_ref = i;
  228.         if (last_xab != 0L)
  229.             last_xab->xab$l_nxt = (char*)k;
  230.         last_xab = (xabptr)k;
  231.     }
  232.     for (i = 0; i < na; i++)
  233.     {
  234.         struct XABALL *a;
  235.         INIT(a, XALLL, cc$rms_xaball);
  236.         a->xab$b_aid = i;
  237.         if (last_xab != 0L)
  238.             last_xab->xab$l_nxt = (char*)a;
  239.         last_xab = (xabptr)a;
  240.     }
  241.  
  242.     fab.fab$l_xab = (char*)xab_chain;
  243. #ifdef DEBUG
  244.     printf("Dump of XAB chain before DISPLAY:\n");
  245.     for (x = xab_chain; x != 0L; x = x->xab$l_nxt)
  246.         dump_rms_block(x);
  247. #endif
  248.     /*
  249.     *   Get information on the file structure etc.
  250.     */
  251.     status = sys$display(&fab, 0, 0);
  252.     if (ERR(status))
  253.     {
  254. #ifdef DEBUG
  255.         printf("get_vms_attributes: sys$display for file %s:\n  error status = %d\n",
  256.                z->name, status);
  257. #endif
  258.         goto err_exit;
  259.     }
  260.  
  261. #ifdef DEBUG
  262.     printf("\nDump of XAB chain after DISPLAY:\n");
  263.     for (x = xab_chain; x != 0L; x = x->xab$l_nxt)
  264.         dump_rms_block(x);
  265. #endif
  266.  
  267.     fab.fab$l_xab = 0;  /* Keep XABs */
  268.     status = sys$close(&fab);
  269.     if (ERR(status))
  270.     {
  271. #ifdef DEBUG
  272.         printf("get_vms_attributes: sys$close for file %s:\n  error status = %d\n",
  273.                z->name, status);
  274. #endif
  275.         goto err_exit;
  276.     }
  277.  
  278.     extra_l = EXTL0 + nk * (XKEYL + EXTHL) + na * (XALLL + EXTHL);
  279. #ifndef OLD_COMPRESS
  280.     extra_l += PAD0 + (nk+na) * PAD;
  281. #endif
  282.  
  283.     if( verlen = get_vms_version(verbuf,sizeof(verbuf)) )
  284.     {   extra_l += verlen + EXTHL;
  285. #ifndef OLD_COMPRESS
  286.         extra_l += PAD;
  287. #endif
  288.     }
  289.  
  290.     if ((scan = extra = (uch *) malloc(extra_l)) == (uch*)NULL)
  291.     {
  292. #ifdef DEBUG
  293.         printf("get_vms_attributes: Insufficient memory to allocate extra buffer\n");
  294. #endif
  295.         goto err_exit;
  296.     }
  297.  
  298.  
  299.     if( verlen > 0 )
  300.         scan = _compress_block(scan,verbuf, verlen, VERSIG);
  301.  
  302.     /*
  303.      *  Zero all unusable fields to improve compression
  304.